﻿using JzSport.Model.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JzSport.Model
{
    /// <summary>
    /// 验证码服务
    /// </summary>
    public class VerifycodeService
    {
        IValidationStrategy _validationStrategy = new ValidationStrategy();

        /// <summary>
        /// 发送手机注册时的验证码
        /// </summary>
        /// <param name="phone"></param>
        /// <returns></returns>
        public ServiceResult<Verifycode> Send4RegisterByPhone(string phone, int timeoutMinute)
        {
            if (!_validationStrategy.ValidatePhone(phone))
            {
                return new ServiceResult<Verifycode>(ErrorCode.SendVerifycode_InvalidPhone);
            }

            Verifycode verifycode = null;
            using (JzSportDbContext dbContext = new JzSportDbContext())
            {
                // 验证手机是否已注册
                AccountRepository accountReps = new AccountRepository(dbContext);
                if (accountReps.GetByPhone(phone) != null)
                {
                    return new ServiceResult<Verifycode>(ErrorCode.SendVerifycode_PhoneRegistered);
                }

                VerifycodeRepository resp = new VerifycodeRepository(dbContext);

                verifycode = resp.GetByPhone(phone, UsageCode.Register);

                if (verifycode == null)
                {
                    // 生成一个新的验证码
                    verifycode = new Verifycode();
                    verifycode.Id = Guid.NewGuid();
                    verifycode.Phone = phone;
                    verifycode.Usage = UsageCode.Register;
                    verifycode.Value = new Random().Next(1000, 9999).ToString();
                    verifycode.CreatedTime = DateTime.Now;
                    verifycode.TimeoutTime = verifycode.CreatedTime.AddMinutes(1);

                    resp.Create(verifycode);
                    if (dbContext.SaveChanges() <= 0)
                    {
                        // 创建验证码失败
                        return new ServiceResult<Verifycode>(ErrorCode.DB_Error, null);
                    }
                }
                else
                {
                    if (verifycode.TimeoutTime <= DateTime.Now)
                    {
                        // 验证码已过去，生成一个新的验证码
                        verifycode.Value = new Random().Next(1000, 9999).ToString();
                        verifycode.CreatedTime = DateTime.Now;
                        verifycode.TimeoutTime = verifycode.CreatedTime.AddMinutes(1);

                        resp.Update(verifycode.Id, verifycode);

                        if (dbContext.SaveChanges() <= 0)
                        {
                            // 创建验证码失败
                            return new ServiceResult<Verifycode>(ErrorCode.DB_Error, null);
                        }
                    }
                }
            }

            string retMsg = string.Empty;
            if (!MessageUtil.Send(phone, verifycode.Value, timeoutMinute, out retMsg))
            {
                // 发送失败
                return new ServiceResult<Verifycode>(ErrorCode.SendVerifycode_SendFailure);
            }
            // 发送验证码
            return new ServiceResult<Verifycode>(ErrorCode.NoError, verifycode);
        }

        /// <summary>
        /// 发送找回密码时的验证码
        /// </summary>
        /// <param name="phone"></param>
        /// <returns></returns>
        public ServiceResult<Verifycode> Send4ForgottenPassword(string phone, int timeoutMinute)
        {
            if (!_validationStrategy.ValidatePhone(phone))
            {
                return new ServiceResult<Verifycode>(ErrorCode.SendVerifycode_InvalidPhone);
            }

            Verifycode verifycode = null;
            using (JzSportDbContext dbContext = new JzSportDbContext())
            {
                // 验证手机是否已注册
                AccountRepository accountReps = new AccountRepository(dbContext);
                if (accountReps.GetByPhone(phone) == null)
                {
                    return new ServiceResult<Verifycode>(ErrorCode.SendVerifycode_PhoneUnregistered);
                }

                VerifycodeRepository resp = new VerifycodeRepository(dbContext);

                verifycode = resp.GetByPhone(phone, UsageCode.ForgottenPassword);

                if (verifycode == null)
                {
                    // 生成一个新的验证码
                    verifycode = new Verifycode();
                    verifycode.Id = Guid.NewGuid();
                    verifycode.Phone = phone;
                    verifycode.Usage = UsageCode.ForgottenPassword;
                    verifycode.Value = new Random().Next(1000, 9999).ToString();
                    verifycode.CreatedTime = DateTime.Now;
                    verifycode.TimeoutTime = verifycode.CreatedTime.AddMinutes(1);

                    resp.Create(verifycode);
                    if (dbContext.SaveChanges() <= 0)
                    {
                        // 创建验证码失败
                        return new ServiceResult<Verifycode>(ErrorCode.DB_Error, null);
                    }
                }
                else
                {
                    if (verifycode.TimeoutTime <= DateTime.Now)
                    {
                        // 验证码已过去，生成一个新的验证码
                        verifycode.Value = new Random().Next(1000, 9999).ToString();
                        verifycode.CreatedTime = DateTime.Now;
                        verifycode.TimeoutTime = verifycode.CreatedTime.AddMinutes(1);

                        resp.Update(verifycode.Id, verifycode);

                        if (dbContext.SaveChanges() <= 0)
                        {
                            // 创建验证码失败
                            return new ServiceResult<Verifycode>(ErrorCode.DB_Error, null);
                        }
                    }
                }
            }

            string retMsg = string.Empty;
            if (!MessageUtil.Send4Forgotten(phone, verifycode.Value, timeoutMinute, out retMsg))
            {
                // 发送失败
                return new ServiceResult<Verifycode>(ErrorCode.SendVerifycode_SendFailure);
            }
            // 发送验证码
            return new ServiceResult<Verifycode>(ErrorCode.NoError, verifycode);
        }
    }
}
